﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;

using Omron.Framework;
using Omron.Framework.Networking;
using Omron.Actors;

namespace Omron.GameStates
{
    partial class OmronMainStageV1 : GameState
    {
        public OmronMainStageV1() 
        {
        }

        GameLoopTimer motionT, fastT, slowT;
        public override void Init()
        {
            //ResourceManager.GraphicsDeviceManager.PreferredBackBufferWidth = GraphicsAdapter.DefaultAdapter.CurrentDisplayMode.Width;
            //ResourceManager.GraphicsDeviceManager.PreferredBackBufferHeight = GraphicsAdapter.DefaultAdapter.CurrentDisplayMode.Height;
            //ResourceManager.GraphicsDeviceManager.IsFullScreen = true;
            //ResourceManager.GraphicsDeviceManager.ApplyChanges();

            motionT = new GameLoopTimer(1000d / 60d);
            motionT.Update += new Action<GameTime>(motionT_Update);

            fastT = new GameLoopTimer(1000d / 60d);
            fastT.Update += new Action<GameTime>(fastT_Update);

            slowT = new GameLoopTimer(1000d / 2d);
            slowT.Update += new Action<GameTime>(slowT_Update);



            spriteBatch = new SpriteBatch(this.GraphicsDevice);


            float w = GraphicsDevice.PresentationParameters.BackBufferWidth;
            float h = GraphicsDevice.PresentationParameters.BackBufferHeight;
            UIMan = new UIManager();
            UIMan.MouseLeftDown += new MouseClickEventHandler(UIMan_MouseLeftDown);
            UIMan.MouseRightUp += new MouseClickEventHandler(UIMan_MouseRightUp);
            UIMan.MouseRightDown += new MouseClickEventHandler(UIMan_MouseRightDown);
            UIMan.KeyDown += new KeyPressEventHandler(UIMan_KeyDown);
            UIMan.KeyHeld += new KeyPressEventHandler(UIMan_KeyHeld);
            UIMan.MouseOver += new MouseOverEventHandler(UIMan_MouseOver);

            metalText = new Text(new Vector2(10, 10), "metal: 0", "UnitMenuFont");
            metalText.Color = Color.Firebrick;
            UIMan.AddControl(metalText);

            debugText = new Text(new Vector2(w - 200, 10), "debug text here", "UnitMenuFont");
            debugText.Color = Color.Red;
            UIMan.AddControl(debugText);

            activeUnits = new List<Actor>();




            world = new World(100, 100, Settings["Grid Size"]);
            var cent = 0.5f * world.TileGrid.UVToScreen(new Point(world.TileGrid.U_length - 1, world.TileGrid.V_length - 1));
            
            ActiveCam = new Camera(GraphicsDevice.Viewport);
            //ActiveCam.Target = Vector2.Zero;
            ActiveCam.Target = cent; //target camera on center of tile grid
            ActiveCam.Zoom = 85f;


            playerF = new Faction(world);
            playerF.Resources.Metal = 30000;
            playerF.Resources.Crystal = 400;
            Faction wumpusF = new Faction(world);
            wumpusF.Resources.Crystal = 30000;

            playerF.Register(wumpusF, FactionRelationship.Hostile);
            //playerF.BuildingsUnlocked.Add("DefenseDept_h");
            //playerF.BuildingsUnlocked.Add("DefenseDept_w");
            //playerF.BuildingsUnlocked.Add("Baraks");
            //playerF.BuildingsUnlocked.Add("Outpost");
            //playerF.BuildingsUnlocked.Add("Spawning Pit");
            //playerF.BuildingsUnlocked.Add("Slime Pit");
            //playerF.BuildingsUnlocked.Add("Killer Growth");
            playerF.BuildingsUnlocked.Add("Fence");
            playerF.BuildingsUnlocked.Add("GuardTower");


            MapGenerator.renewSeed();
            MapGenerator.GeneratePerlinMap(world);

            setupHumanBase(ActiveCam.Target, playerF);
            setupWumpusBase(ActiveCam.Target + Vector2.One * 10f, wumpusF);


            //setting up minimap rectangle and stuff lol
            minMapRect = ResourceManager.Resources["Settings"]["Minimap"];
            minMapRect = new Rectangle(GraphicsDevice.PresentationParameters.BackBufferWidth - minMapRect.Width,
                GraphicsDevice.PresentationParameters.BackBufferHeight - minMapRect.Height, minMapRect.Width,
                minMapRect.Height);
            
            

            miniMapCam = new Camera(new Viewport(minMapRect));
            minimapButton = new SolidButton(new Vector2(minMapRect.X, minMapRect.Y), 
                minMapRect.Width, minMapRect.Height);
            minimapButton.MouseDrag += new MouseOverEventHandler(minimapButton_MouseDrag);
            UIMan.AddControl(minimapButton);
            UIMan.MouseLeftHeld += new MouseClickEventHandler(UIMan_MouseLeftHeld);
            UIMan.MouseLeftUp += new MouseClickEventHandler(UIMan_MouseLeftUp);


            gameUI = new GameUI(GraphicsDevice.PresentationParameters.BackBufferWidth, GraphicsDevice.PresentationParameters.BackBufferHeight,
                playerF, UIMan, world, activeUnits, factionMenu_ItemPressed, false);


            startAllTimers();
        }

        void startAllTimers()
        {
            slowT.Start();
            fastT.Start();
            motionT.Start();
        }

        void slowT_Update(GameTime obj)
        {
            world.UpdateActorSlowOnly(obj);
        }

        void fastT_Update(GameTime obj)
        {
            world.UpdateActorFastOnly(obj);
            world.UpdateEffectsOnly(obj);
        }

        void motionT_Update(GameTime obj)
        {
            world.UpdateMotionOnly(obj);
        }

        void minimapButton_MouseDrag(Vector2 mPos)
        {
            Vector2 gamePos = Vector2.Transform(mPos - new Vector2(minMapRect.X, minMapRect.Y), miniMapCam.GetUntransform());
            ActiveCam.Target = gamePos;

            selectUponRelease = false;
        }

        void factionMenu_ItemPressed(int itemKey)
        {
            string curBuild = playerF.BuildingsUnlocked[itemKey];
            Vector2 mPos = Vector2.Transform(UIMan.GetMousePos(), ActiveCam.GetUntransform());
            buildingActor = UnitConverter.CreateActor(curBuild, mPos, playerF);
            buildColides = true;
            buildingActor.SetBaseAnimation((buildingActor as FatherBuilding).IdleAnimation);
            UIMan.ResetScroll();
        }

        void setupHumanBase(Vector2 basePos, Faction faction)
        {
            var factory = UnitConverter.CreateActor("GuardTower", basePos, faction);
            world.AddActor(factory);
            topLeft = basePos;
            botomRight = basePos + new Vector2(0.1f, 0.1f);

            float fClear = 10f;

            var factSurround = new RectPoly(basePos, fClear, fClear, 0f);
            var acts = world.Query(factSurround);
            foreach (var actor in acts)
            {
                if (actor is Wall || actor is Resource)
                    actor.Die();
            }

            world.AddActor(UnitConverter.CreateActor("Balrog", basePos + Vector2.One, faction));

            for (int i = 0; i < 3; i++)
            {
                var pos = basePos + Vector2.UnitX * ((float)MathHelper.Rand.NextDouble() * 2 - 1f) * (fClear / 2) + Vector2.UnitY * ((float)MathHelper.Rand.NextDouble() * 2 - 1f) * (fClear / 2);
                world.AddActor(UnitConverter.CreateActor("GelCube", pos, faction));
            }
            for (int i = 0; i < 10; i++)
            {
                var pos = basePos + Vector2.UnitX * ((float)MathHelper.Rand.NextDouble() * 2 - 1f) * (fClear / 2) + Vector2.UnitY * ((float)MathHelper.Rand.NextDouble() * 2 - 1f) * (fClear / 2);
                world.AddActor(UnitConverter.CreateActor("Ranger", pos, faction));
            } 
            for (int i = 0; i < 10; i++)
            {
                var pos = basePos + Vector2.UnitX * ((float)MathHelper.Rand.NextDouble() * 2 - 1f) * (fClear / 2) + Vector2.UnitY * ((float)MathHelper.Rand.NextDouble() * 2 - 1f) * (fClear / 2);
                world.AddActor(UnitConverter.CreateActor("Troy", pos, faction));
            } 
        }

        void setupWumpusBase(Vector2 basePos, Faction faction)
        {//put wumpus targes here
            var factory = UnitConverter.CreateActor("Spawning Pit", basePos, faction);
            world.AddActor(factory);
            topLeft = basePos;
            botomRight = basePos + new Vector2(0.1f, 0.1f);

            float fClear = 10f;

            var factSurround = new RectPoly(basePos, fClear, fClear, 0f);
            var acts = world.Query(factSurround);
            foreach (var actor in acts)
            {
                if (actor is Wall || actor is Resource)
                    actor.Die();
            }

            for (int i = 0; i < 20; i++)
            {
                var pos = basePos + Vector2.UnitX * ((float)MathHelper.Rand.NextDouble() * 2 - 1f) * (fClear / 2) + Vector2.UnitY * ((float)MathHelper.Rand.NextDouble() * 2 - 1f) * (fClear / 2);
                world.AddActor(UnitConverter.CreateActor("Dark Magus", pos, faction));
            }
            for (int i = 0; i < 100; i++)
            {
                var pos = basePos + Vector2.UnitX * ((float)MathHelper.Rand.NextDouble() * 2 - 1f) * (fClear / 2) + Vector2.UnitY * ((float)MathHelper.Rand.NextDouble() * 2 - 1f) * (fClear / 2);
                world.AddActor(UnitConverter.CreateActor("Mite", pos, faction));
            }
        }

        public static Dictionary<string, dynamic> Settings;

        GameUI gameUI;
        UIManager UIMan;

        Camera ActiveCam;

        SpriteBatch spriteBatch;

        World world;

        Tile activeTile = null;
        List<Actor> activeUnits;
        Faction playerF;

        Actor buildingActor;
        bool buildColides;

        public Text metalText, debugText;
        SolidButton minimapButton;

        void UIMan_MouseOver(Vector2 mPos)
        {
            //for moving screen
            Vector2 screenCenter = new Vector2(GraphicsDevice.PresentationParameters.BackBufferWidth / 2,
                GraphicsDevice.PresentationParameters.BackBufferHeight / 2);
            Vector2 diffVect = UIMan.GetMousePos() - screenCenter;
            diffVect.X /= screenCenter.X;
            diffVect.Y /= -screenCenter.Y;
            if ((Math.Abs(diffVect.X) > Settings["X Scroll"]) || (Math.Abs(diffVect.Y) > Settings["Y Scroll"]))//move only if cursur is on the outer strip circle
            {
                ActiveCam.Target += diffVect * Settings["Camera Speed"] / ActiveCam.Zoom;
            }
        }

        public override void Update(GameTime gameTime)
        {
            metalText.TextMsg = "metal: " + playerF.Resources.Metal+ "\nCyrstal: " + playerF.Resources.Crystal;

            string debugStr = activeUnits.Select(u => u.ActorID).Aggregate("", (s, u) => s += u.ToString() + ", ");
            debugText.TextMsg = debugStr;

            //world.UpdateAll(gameTime);
            UIMan.Update();
            gameUI.UpdateActMenu();

            //ui stuff
            Vector2 mPos = UIMan.GetMousePos();
            Vector2 gamePt = Vector2.Transform(mPos, ActiveCam.GetUntransform());
            Point uvPt = world.TileGrid.ScreenToUV(gamePt);

            if (world.TileGrid.IsValidUV(uvPt))
            {
                activeTile = world.TileGrid[uvPt];
            }
            else
            {
                activeTile = null;
            }

            if (buildingActor != null)
            {
                if (ResourceManager.Resources[buildingActor.Type].CanRotate && (prevBuild == null))
                    buildingActor.Rotation = -(float)Math.PI * 2 * ((float)UIMan.ScrollValue / 10000) * ResourceManager.Resources["Settings"]["BuildScroll"];
                buildingActor.Position = gamePt;
                buildColides = world.isColliding(buildingActor);
            }

        }

        Vector2? prevBuild;

        void UIMan_MouseLeftHeld(Vector2 mPos)
        {
            if ((buildingActor != null) && !buildColides && (buildingActor is Wall))
            {
                if (prevBuild != null)
                {
                    buildingActor.Rotation = MathHelper.GetAngle(buildingActor.Position - prevBuild.Value);
                }
                Actor build = UnitConverter.CreateActor(buildingActor.Type, buildingActor.Position, buildingActor.Faction);
                build.Rotation = buildingActor.Rotation;
                prevBuild = build.Position;
                world.AddActor(build);
            }
        }

        void UIMan_MouseLeftUp(Vector2 mPos)
        {
            buildingActor = null;
            prevBuild = null;
        }

        void UIMan_MouseLeftDown(Vector2 mPos)
        {
            //called when moused is pressed
            Vector2 gamePt = Vector2.Transform(mPos, ActiveCam.GetUntransform());

            var coverActor = world.Query(new RectPoly(gamePt, gamePt)).FirstOrDefault();

            if ((buildingActor != null) && !buildColides && !(buildingActor is Wall))
            {
                buildingActor.SetBaseAnimation((buildingActor as FatherBuilding).BuildAnimation);
                (buildingActor as FatherBuilding).BuildAnimation.Stop();
                world.AddActor(buildingActor);
                return;
            }

            foreach (Actor unit in activeUnits)
            {
                if (unit is FatherUnit)
                {

                    if (coverActor != null)
                    {
                        if (coverActor.Faction.GetRelationship(playerF) != FactionRelationship.Allied)
                            (unit as FatherUnit).AI.Engage(coverActor);
                        else if (coverActor is FatherBuilding && !(coverActor as FatherBuilding).IsComplete)
                            (unit as FatherUnit).AI.Build(coverActor as FatherBuilding);
                    }
                    else
                    {
                        if (UIMan.CtrlDown)
                            (unit as FatherUnit).MayhamTrack(gamePt);
                        else
                            (unit as FatherUnit).Track(gamePt);
                    }
                }
            }
        }

        void UnselectUnits()
        {
            foreach (Actor actor in activeUnits)
                actor.IsSelected = false;
            activeUnits.Clear();
            gameUI.UpdateSelectedAndMenu();
        }

        void SelectUnit(Vector2 mPos)
        {
            Vector2 gamePt = Vector2.Transform(mPos, ActiveCam.GetUntransform());
            var min = Vector2.Min(selectionMPos, gamePt);
            var max = Vector2.Max(selectionMPos, gamePt);

            RectPoly testpoint = new RectPoly(min, max);

            foreach (var actor in world.Query(testpoint))
            {
                if (selType)
                {
                    SelectType(actor);
                    break;
                }
                if (activeUnits.Contains(actor))
                {
                    if (invSelection)
                    {
                        actor.IsSelected = false;
                        activeUnits.Remove(actor);
                    }
                    continue;
                }
                //if (actor.Faction == playerF || (actor.Faction == world.Faction && actor is Resource)) //normal faction-only selection
                if(!(actor is Wall)) //god-mode
                {
                    Actor activeUnit = actor;
                    activeUnit.IsSelected = true;
                    activeUnits.Add(activeUnit);
                }
            }
            gameUI.UpdateSelectedAndMenu();
        }

        void SelectType(Actor actor)
        {
            for (int i = activeUnits.Count - 1; i >= 0; i--)
            {
                if (activeUnits[i].Type != actor.Type)
                {
                    activeUnits[i].IsSelected = false;
                    activeUnits.RemoveAt(i);
                }
            }
            if (actor.Menu == null)
                gameUI.UpdateSelectedAndMenu();
        }

        Vector2 selectionMPos;
        bool selectUponRelease = false;
        bool invSelection = false;
        bool selType = false;

        void UIMan_MouseRightDown(Vector2 mPos)
        {
            buildingActor = null;
            if (!UIMan.ShiftDown && !UIMan.CtrlDown && !UIMan.AltDown)
                UnselectUnits();
            if (UIMan.CtrlDown)
                invSelection = true;
            if (UIMan.AltDown)
                selType = true;
            selectUponRelease = true;
            selectionMPos = Vector2.Transform(mPos, ActiveCam.GetUntransform());
        }

        void UIMan_MouseRightUp(Vector2 mPos)
        {
            if (selectUponRelease)
            {
                SelectUnit(mPos);
                selectUponRelease = false;
                invSelection = false;
                selType = false;
            }
        }

        void UIMan_KeyDown(Keys key)
        {
            switch (key)
            {
                case Keys.Escape:
                    GameEngine.PopState();
                    break;
                case Keys.B:
                    if (activeUnits.Count > 0 && (activeUnits[0] is FatherBuilding))
                    {
                        (activeUnits[0] as FatherBuilding).OnWorkedOn(10);
                    }
                    break;
                case Keys.OemTilde:
                    playerF.FOW.DiscoverAll();
                    break;
                case Keys.OemPlus:
                    ActiveCam.Zoom *= 2f;
                    break;
                case Keys.OemMinus:
                    ActiveCam.Zoom /= 2f;
                    break;                                                                                                                                                                                                                                                         case Keys.OemPipe: if (UIMan.AltDown && UIMan.CtrlDown) { playerF.Resources.Metal += 1000; playerF.Resources.Crystal += 1000; } break;
                case Keys.A:
                    foreach (Actor actor in activeUnits)
                    {
                        if (actor is FatherUnit)
                        {
                            (actor as FatherUnit).IssueRangedAttack(Vector2.Transform(UIMan.GetMousePos(),ActiveCam.GetUntransform()));
                        }
                    }
                    break;
                case Keys.Home:
                    ResourceManager.GraphicsDeviceManager.PreferredBackBufferWidth = GraphicsAdapter.DefaultAdapter.CurrentDisplayMode.Width;
                    ResourceManager.GraphicsDeviceManager.PreferredBackBufferHeight = GraphicsAdapter.DefaultAdapter.CurrentDisplayMode.Height;
                    ResourceManager.GraphicsDeviceManager.ToggleFullScreen();
                    ResourceManager.GraphicsDeviceManager.ApplyChanges();
                    break;
                default:
                    break;
            }
        }

        void UIMan_KeyHeld(Keys key)
        {
            switch (key)
            {
                case Keys.Up:
                    ActiveCam.Target += Vector2.UnitY * Settings["Camera Speed"] / ActiveCam.Zoom;
                    break;
                case Keys.Down:
                    ActiveCam.Target -= Vector2.UnitY * Settings["Camera Speed"] / ActiveCam.Zoom;
                    break;
                case Keys.Left:
                    ActiveCam.Target -= Vector2.UnitX * Settings["Camera Speed"] / ActiveCam.Zoom;
                    break;
                case Keys.Right:
                    ActiveCam.Target += Vector2.UnitX * Settings["Camera Speed"] / ActiveCam.Zoom;
                    break;
            }
        }


        Rectangle minMapRect;// = new Rectangle(0, 0, 300, 300);
        Vector2 topLeft;// = new Vector2(0, -85);
        Vector2 botomRight;// = new Vector2(300, 85);
        Camera miniMapCam;

        void updateMinimapCam()
        {

            float maxX = botomRight.X - topLeft.X;
            float maxY = botomRight.Y - topLeft.Y;
            float zoomX = minMapRect.Width / maxX;
            float zoomY = minMapRect.Height / maxY;

            miniMapCam.Zoom = Math.Min(zoomX, zoomY);
            miniMapCam.Target = (topLeft + botomRight) / 2;
        }

        public override void Draw(GameTime gameTime)
        {
            
            HashSet<Actor> visibleActors = world.QueryVisibleActors(playerF.FOW);

            //rendering mini map
            //minimap
            updateMinimapCam();
            RenderTarget2D miniMapRender = new RenderTarget2D(GraphicsDevice, minMapRect.Width, minMapRect.Height, false, GraphicsDevice.DisplayMode.Format, DepthFormat.Depth24);
            GraphicsDevice.SetRenderTarget(miniMapRender);
                        GraphicsDevice.Clear(Color.Black);
                        spriteBatch.Begin(SpriteSortMode.BackToFront, BlendState.AlphaBlend, null, null, null, null, miniMapCam.GetTransform());

            for (int u = 0; u < world.TileGrid.U_length; u++)
            {
                for (int v = 0; v < world.TileGrid.V_length; v++)
                {
                    var tile = world.TileGrid[u, v];

                    
                    //coloration
                    var tState = playerF.FOW.GetTileState(u, v);
                    if (tState != TileState.Undiscovered)
                    {
                        topLeft = Vector2.Min(topLeft, tile.Position);
                        botomRight = Vector2.Max(botomRight, tile.Position);

                        Color c = Color.Red;
                        if (tState == TileState.Inactive)
                            c = Color.DarkGray;
                        if (tState == TileState.Active)
                            c = Color.LightGray;
                        drawHex(tile.Position, world.TileGrid.HexSideLen, c);
                    }
                }
            }
            foreach (Actor act in visibleActors)
            {
                if (act.CollisionClass != CollisionClass.IsolatedNoPersist)
                {
                    if (act.Faction == world.Faction)
                        act.Draw(spriteBatch);
                    else
                    {
                        Color col = act.Faction.GetColor();
                        if (activeUnits.Contains(act))
                        {
                            col.R = (byte)Math.Min(col.R + 60, 255);
                            col.G = (byte)Math.Min(col.G + 60, 255);
                            col.B = (byte)Math.Min(col.B + 60, 255);
                        }
                        GraphicsHelper.DrawRectangleInv(spriteBatch, act.Position, act.GetBoundingPoly().MaxRadius * 4,
                            act.GetBoundingPoly().MaxRadius * 4, 0, col);
                    }
                }
            }

            spriteBatch.End();
            GraphicsDevice.SetRenderTarget(null);
            GraphicsDevice.Clear(Color.Black);
            

            spriteBatch.Begin(SpriteSortMode.BackToFront, BlendState.AlphaBlend, null, null, null, null, ActiveCam.GetTransform());

            for (int u = 0; u < world.TileGrid.U_length; u++)
            {
                for (int v = 0; v < world.TileGrid.V_length; v++)
                {
                    var tile = world.TileGrid[u, v];

                    //coloration
                    var tState = playerF.FOW.GetTileState(u, v);
                    if (tState != TileState.Undiscovered)
                    {
                        Color c = Color.Red;
                        if (tState == TileState.Inactive)
                            c = Color.DarkGray;
                        if (tState == TileState.Active)
                            c = Color.LightGray;
                        drawHex(tile.Position, world.TileGrid.HexSideLen, c);
                    }
                }
            }

            /*if (activeTile != null)
            {
                drawHex(activeTile.Position, world.TileGrid.HexSideLen, Color.Crimson * 0.5f);
            }*/
            
            foreach (Actor actor in visibleActors)
            {
                actor.Draw(spriteBatch);
                //GraphicsHelper.DrawBallInv(spriteBatch, ResourceManager.Resources["disk"], actor.Position, actor.SightRange, Color.Blue * 0.1f, 0.5f);
            }

            foreach (Actor actor in world.GetActors())
            {
                if (actor.CollisionClass == CollisionClass.IsolatedNoPersist)
                {
                    var posUV = actor.GetPosUV();
                    if (playerF.FOW.GetTileState(posUV.X, posUV.Y) == TileState.Active) //only draw isolated actors above active tiles
                        actor.Draw(spriteBatch);
                }
            }

            foreach (var effect in world.GetEffects())
            {
                var posUV = world.TileGrid.ScreenToUV(effect.MainPos);
                if (playerF.FOW.GetTileState(posUV.X, posUV.Y) == TileState.Active) //only draw effects positioned above active tiles
                    effect.Draw(spriteBatch);
            }

            if (buildingActor != null)
            {//draw the building where the cursor is
                Color col = Color.White;
                if (buildColides)
                    col = Color.Red;
                buildingActor.GetActiveAnimation().GetCurrentFrame().Draw(spriteBatch, buildingActor.Position, 
                    buildingActor.Rotation, col);
            }

            spriteBatch.End();



            spriteBatch.Begin(); //restart without cam matrix for UI drawing
            //selection draw
            if (selectUponRelease)
            {
                Vector2 realSelPos = Vector2.Transform(selectionMPos, ActiveCam.GetTransform());
                
                var mPos = UIMan.GetMousePos();
                Vector2 min = Vector2.Min(mPos, realSelPos);
                Vector2 max = Vector2.Max(mPos, realSelPos);

                spriteBatch.Draw(ResourceManager.Resources["pixel"], new Rectangle((int)min.X, (int)min.Y, (int)(max.X - min.X), (int)(max.Y - min.Y)), Color.LightBlue * 0.3f);
            }
            UIMan.Draw(spriteBatch);

            spriteBatch.Draw((Texture2D)miniMapRender, minMapRect, Color.White);
            
            Vector2 camBounds = new Vector2(ActiveCam.GetWidth(), ActiveCam.GetHeight());
            Vector2 minGPt = new Vector2(ActiveCam.Target.X - camBounds.X / 2, ActiveCam.Target.Y + camBounds.Y / 2);
            Vector2 maxGPt = new Vector2(ActiveCam.Target.X + camBounds.X / 2, ActiveCam.Target.Y - camBounds.Y / 2);

            Vector2 min_mPt = Vector2.Transform(minGPt, miniMapCam.GetTransform());
            //Vector2 max_mPt = Vector2.Transform(maxGPt, miniMapCam.GetTransform());
            float mmwid = ActiveCam.GetWidth() * miniMapCam.Zoom;
            float mmheight = ActiveCam.GetHeight() * miniMapCam.Zoom;
            Vector2 max_mPt = min_mPt + new Vector2(mmwid, mmheight); ;

            if (min_mPt.X < 0) min_mPt.X = 0;
            if (min_mPt.Y < 0) min_mPt.Y = 0;
            if (max_mPt.X > minMapRect.Width) max_mPt.X = minMapRect.Width;
            if (max_mPt.Y > minMapRect.Height) max_mPt.Y = minMapRect.Height;

            GraphicsHelper.DrawRectOutline(spriteBatch, min_mPt.X + minMapRect.X, min_mPt.Y + minMapRect.Y, max_mPt.X-min_mPt.X, max_mPt.Y- min_mPt.Y, 2f, Color.Red);
            GraphicsHelper.DrawRectOutline(spriteBatch, minMapRect.X, minMapRect.Y, minMapRect.Width, minMapRect.Height, 5f, Color.ForestGreen);

            
            spriteBatch.End();
        }

        void drawHex(Vector2 pos, float sideLen, Color c)
        {
            var hexTex = ResourceManager.Resources["hex"];
            spriteBatch.Draw(hexTex, pos, null, c, 0.0f, new Vector2(hexTex.Width / 2, hexTex.Height / 2), new Vector2(2 * sideLen / hexTex.Width, -2 * sideLen / hexTex.Height), SpriteEffects.None, 0.9f);  //height is scaled -1 since y-axis gets flipped
        }
    }
}
